今天將 Bot 部署至 Railway,完成 Google OAuth 雲端設定,並驗證本機 Bot 停止後,仍能透過 Discord 新增、查詢及刪除 Google Calendar 行程。
在 Railway 選擇 Deploy from GitHub Repo,連接專案,啟動指令設為 npm start,對應 node src/index.js。
本機的 .env 不會隨 GitHub 上傳,因此要在 Railway Variables 設定:
DISCORD_TOKEN=Discord Bot Token
CLIENT_ID=Discord Application ID
GUILD_ID=Discord Server ID
GOOGLE_CALENDAR_ID=primary
部署後確認服務為 Online、最新部署為 Active,再從 Deploy Logs 檢查 Bot 是否成功登入。

圖 1:服務 Online,最新部署 Active。

圖 2:雲端執行 npm start,Bot 登入成功。
第一次測試 /list 出現授權錯誤。原因是原本的 OAuth 模組只會讀取本機 credentials.json 與 token.json,這些敏感檔案未上傳 GitHub,Railway 也無法直接取得。
修改 src/auth/googleAuth.js,讓 loadClient() 優先讀取三個環境變數:
| 變數 | 值的來源 |
|---|---|
GOOGLE_CLIENT_ID |
credentials.json 的 installed.client_id |
GOOGLE_CLIENT_SECRET |
credentials.json 的 installed.client_secret |
GOOGLE_REFRESH_TOKEN |
token.json 的 refresh_token |
三項齊全時建立 OAuth Client,使用 Refresh Token 更新 Access Token;只設定部分變數時回報設定不完整。沒有設定雲端變數時,保留原本的本機 JSON 授權流程。
修改後執行 npm test,再推送 GitHub。此次 113 項測試通過,GitHub Actions 也成功完成。

圖 3:新版 OAuth 程式已推送,CI 測試通過。
將三個 Google OAuth 變數加入 Railway Variables,再部署變更。憑證只存入環境變數,不提交 GitHub。

圖 4:Google OAuth 變數已設定,畫面中的值皆遮罩。
資料流程為:Discord 指令 → Railway Bot → Google OAuth → Google Calendar API → Discord 回覆。
驗收期間本機 Bot 未啟動,以下指令由 Railway 處理。
/add title:Day29_Railway_Verify_20261018 date:20261019 time:1830
Bot 成功建立台灣時間 18:30~19:30 的行程,預設提前 10 分鐘提醒。再開啟行程連結,確認資料實際出現在 Google Calendar。

圖 5:/add 回覆行程時間、時區及提醒資訊。

圖 6:Google Calendar 中可看到相同的測試行程。
先使用測試行程的 ID 執行 /delete,核對名稱與時間;再加上 confirm:true 才正式刪除。
/delete event_id:測試行程ID
/delete event_id:相同測試行程ID confirm:true

圖 7:第一次只顯示預覽,尚未刪除。

圖 8:確認後成功刪除測試行程。
重新整理 Google Calendar,搜尋相同名稱顯示找不到活動;API 讀取該事件的狀態也確認為 cancelled。

圖 9:搜尋測試名稱,確認活動已不存在。
執行 /list,成功取得未來 7 天最早 5 筆行程,確認刪除後雲端仍能正常連線。

圖 10:/list 正常回覆 Google Calendar 行程。
以上完成「本機 Bot 停止後,雲端獨立操作」驗證;本次未實際將 MacBook 關機測試。
.env、credentials.json、token.json 未提交 GitHub。Railway 目前採一般變數遮罩,尚未設定 Sealed。
圖 11:OAuth 仍是外部/測試模式。

圖 12:Railway 試用剩餘時間與額度。
這次主要修正 OAuth 依賴本機檔案的問題。部署驗收除了查看 Online,還要實際發送指令,並到 Google Calendar 核對資料。